package com.view.cn.mvprxjava.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.view.cn.mvprxjava.R;
import com.view.cn.mvprxjava.utils.AIUtils;
import com.view.cn.mvprxjava.utils.PieceUtils;

import java.util.ArrayList;

/**
 * 五子棋游戏
 * Created by Zengxiaoping on 2016/12/13.
 */

public class BackgammonGameView2 extends View {

	public static final int GAMEOVER_WHITE_WINNER = 1;  //白棋选手胜利
	public static final int GAMEOVER_BLACK_WINNER = 2;  //黑棋选手胜利
	public static final int GAMEOVER_DRAW = 3;          //平局

	private static final int MAX_LINE_NUMBER = 10;      //棋盘最大行列数

	private float mPanelWidth;                  //棋盘宽度
	private float mLineHeight;                  //棋盘格子的行高
	private float mPieceScaleRatio = 3.0f / 4;  //棋子缩放比率（行高的3/4）
	private Paint mPaint;                       //画笔
	private Bitmap mBitmapWhite;                //白色旗子图片
	private Bitmap mBitmapBlack;                //黑色旗子图片
	private ArrayList<Point> mArrayListWhite;   //存放白色棋子的集合
	private ArrayList<Point> mArrayListBlack;   //存放黑色棋子的集合
	private boolean mIsFirstWihte = true;       //是否白棋先手
	private boolean mIsGameOver = false;        //是否游戏结束
	private int mGameOverState = -1;            //确定赢家(小于0:未分胜负、0：和局、1：白棋赢、2：黑棋赢)
	private Point mCurrentPoint;                //刚下下来的棋子(用于算法，计算前后时候五子连珠)

	private boolean mMachineGame = false;       //人机对战？
	private OnGameOverLisenter mOnGameOverLisenter; //结束接口

	public void setMachineGame(boolean machineGame) {
		mMachineGame = machineGame;
		resetGame();
	}

	public BackgammonGameView2(Context context) {
		this(context, null);
	}

	public BackgammonGameView2(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		mPaint = new Paint();
		mPaint.setColor(0x88000000);            //设置画笔颜色
		mPaint.setAntiAlias(true);              //设置防抖动
		mPaint.setDither(true);                 //设置抗锯齿
		mPaint.setStyle(Paint.Style.STROKE);    //设置为空心(画线)

		mArrayListWhite = new ArrayList();      //初始化存放白色棋子集合
		mArrayListBlack = new ArrayList();      //初始化存放黑色棋子集合

		mBitmapWhite = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_white_piece);
		mBitmapBlack = BitmapFactory.decodeResource(getResources(), R.mipmap.icon_black_piece);
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);
		int width = Math.min(widthSize, heightSize);

		//此处的逻辑判断是处理当我们自定义的View被嵌套在ScrollView中时,获得的测量模式会是UNSPECIFIED，使得到的widthSize或者heightSize为0
		if (widthMode == MeasureSpec.UNSPECIFIED) {
			width = heightSize;
		} else if (heightMode == MeasureSpec.UNSPECIFIED) {
			width = widthSize;
		}
		setMeasuredDimension(width, width);
	}


	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		mPanelWidth = w;
		mLineHeight = mPanelWidth * 1.0f / MAX_LINE_NUMBER;

		//缩放棋子（根据行高）
		int pieceWidth = (int) (mLineHeight * mPieceScaleRatio);
		mBitmapWhite = Bitmap.createScaledBitmap(mBitmapWhite, pieceWidth, pieceWidth, false);
		mBitmapBlack = Bitmap.createScaledBitmap(mBitmapBlack, pieceWidth, pieceWidth, false);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		drawBoard(canvas);                      //绘制棋盘
		drawPiece(canvas);                      //绘制棋子
//		verificationGameOver(!mIsFirstWihte);    //验证游戏是否结束
	}

	private void drawBoard(Canvas canvas) {
		canvas.save();
		mPaint.setStrokeWidth(2);
		mPaint.setStyle(Paint.Style.FILL);
		for (int i = 0; i < MAX_LINE_NUMBER; i++) {
			int startX = (int) (mLineHeight / 2);
			int endX = (int) (mPanelWidth - mLineHeight / 2);
			int y = (int) ((i + 0.5) * mLineHeight);
			canvas.drawLine(startX, y, endX, y, mPaint);//画横线
			canvas.drawLine(y, startX, y, endX, mPaint);//画竖线
		}
		canvas.restore();
	}

	private void drawPiece(Canvas canvas) {
		canvas.save();
		for (Point point : mArrayListWhite) {
			if (point != null && mBitmapWhite != null) {
				canvas.drawBitmap(mBitmapWhite, (point.x + (1 - mPieceScaleRatio) / 2) * mLineHeight, (point.y + (1 - mPieceScaleRatio) / 2) * mLineHeight, null);
			}
		}
		for (Point point : mArrayListBlack) {
			if (point != null && mBitmapWhite != null) {
				canvas.drawBitmap(mBitmapBlack, (point.x + (1 - mPieceScaleRatio) / 2) * mLineHeight, (point.y + (1 - mPieceScaleRatio) / 2) * mLineHeight, null);
			}
		}
		canvas.restore();
	}

	private void verificationGameOver(boolean isWhite) {
		boolean gameOver = PieceUtils.checkFiveInLine(mCurrentPoint, isWhite ? mArrayListWhite : mArrayListBlack);
		if (gameOver) {
			mOnGameOverLisenter.isGameOver(isWhite ? GAMEOVER_WHITE_WINNER : GAMEOVER_BLACK_WINNER);
		} else if (mArrayListBlack.size() + mArrayListWhite.size() == MAX_LINE_NUMBER * MAX_LINE_NUMBER) {
			mOnGameOverLisenter.isGameOver(GAMEOVER_DRAW);
		}
	}


	/**
	 * 重新开始游戏
	 */
	public void resetGame() {
		mArrayListWhite.clear();
		mArrayListBlack.clear();
		mIsFirstWihte = true;
		mIsGameOver = false;
		mGameOverState = -1;
	}

	/**
	 * 刷新游戏界面
	 */
	public void invaliDate() {
		invalidate();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int eventX = (int) event.getX();
		int eventY = (int) event.getY();

		switch (event.getAction()) {
			case MotionEvent.ACTION_UP:
				Point point = getTouchPoint(eventX, eventY);
				mCurrentPoint = point;
				if (point != null) {
					//如果集合里面已经包含该点，就不做任何操作
					if (mArrayListWhite.contains(point) || mArrayListBlack.contains(point)) {
						return false;
					}
					//是否轮到白棋
					if (mIsFirstWihte) {
						mArrayListWhite.add(point);
					} else {
						mArrayListBlack.add(point);
					}
					verificationGameOver(mIsFirstWihte);    //验证游戏是否结束
					//更换棋手
					mIsFirstWihte = !mIsFirstWihte;
					if (!mIsGameOver && mMachineGame) {
						//算法计算出来的点
						Point pointMachine = AIUtils.getPoint(point, mArrayListWhite, mArrayListBlack);
						mCurrentPoint = pointMachine;
						mArrayListBlack.add(pointMachine);
						verificationGameOver(mIsFirstWihte);    //验证游戏是否结束
						//更换棋手
						mIsFirstWihte = !mIsFirstWihte;
					}
				}
				break;
		}
		//刷新
		invalidate();
		return true;
	}

	/**
	 * 得到触摸位置的点(在棋盘上X：0-9  Y：0-9)
	 *
	 * @param eventX
	 * @param eventY
	 * @return
	 */
	private Point getTouchPoint(int eventX, int eventY) {
		return new Point((int) (eventX / mLineHeight), (int) (eventY / mLineHeight));
	}


	public interface OnGameOverLisenter {
		void isGameOver(int mGameOverState);    //游戏结束(小于0:未分胜负、0：和局、1：白棋赢、2：黑棋赢)

		void isWihte(boolean isWhite);          //轮到谁？
	}

	public void setOnGameOverLisenter(OnGameOverLisenter onGameOverLisenter) {
		this.mOnGameOverLisenter = onGameOverLisenter;
	}
}
